/**
 * @name variable-write search
 * @id python/variable-write-search
 */

import python
import util

Expr getCodeOfWriteAction(Stmt stmt)
{
    isVarReference(stmt) and
    if stmt instanceof AssignStmt then
        result=stmt.(AssignStmt).getValue()
    else if stmt instanceof AugAssign then
        result=stmt.(AugAssign).getValue()
    else
        result=stmt.getASubExpression()
}

string getTargetVarName(Stmt stmt)
{
    isVarReference(stmt) and
    if stmt instanceof AssignStmt then
        result=stmt.(AssignStmt).getTarget(0).toString()
    else if stmt instanceof AugAssign then
        result=stmt.(AugAssign).getTarget().toString()
    else
        result=stmt.toString()
    //result=getSubExprOfAssign(expr).toString()
}

string getOperationName(Stmt stmt)
{
    isVarReference(stmt) and
    if stmt instanceof AssignStmt then
        result="Assign"
    else if stmt instanceof AugAssign then
        result=stmt.(AugAssign).getOperation().getOp().toString()
    else
        result=stmt.toString()
    //result=getSubExprOfAssign(expr).toString()
}

Expr getAllSubExpr(Expr expr)
{
    result=expr.getASubExpression()
}

string exprList2String(ExprList list)
{
    result="" //and
    //forall(Expr expr | expr=list.getAnItem() | result=result+expr.toString())
}

predicate allowIterTypeOfStmt(Stmt stmt) {
    stmt instanceof For or
    stmt instanceof AugAssign or
    stmt instanceof Assign or
    stmt instanceof With or 
    stmt instanceof ExceptStmt
}



Expr iterStmtValue(Stmt stmt)
{
    if stmt instanceof For then
        result=stmt.(For).getIter()
    else if stmt instanceof AugAssign then
        result=stmt.(AugAssign).getValue()
    else if stmt instanceof Assign then
        result=stmt.(Assign).getValue()
    else if stmt instanceof With then
        result=stmt.(With).getContextExpr()
    else if stmt instanceof ExceptStmt then
        result=stmt.(ExceptStmt).getType()
    else
        result=stmt.getASubExpression()
}

Expr iterStmtTarget(Stmt stmt)
{
    allowIterTypeOfStmt(stmt) and
    if stmt instanceof For then
        result=stmt.(For).getTarget()
    else if stmt instanceof AugAssign then
        result=stmt.(AugAssign).getTarget()
    else if stmt instanceof Assign then
        result=stmt.(Assign).getATarget()
    else if stmt instanceof With then
        result=stmt.(With).getOptionalVars()
    else if stmt instanceof ExceptStmt then
        result=stmt.(ExceptStmt).getName()
    else
        result=stmt.getASubExpression()
}



from File f,Module mod,Scope scope,string scopeName,Expr exprBody,Expr exprBodyIter,string dependVar,Expr exprStore,Expr exprStoreIter,string varName,Location location,Stmt stmt, string loc,string storeLoc
where
debug(location) and
isSource(f) and
scope=stmt.getScope() and
mod=scope.getEnclosingModule() and
f=mod.getFile() and

exprStore=iterStmtTarget(stmt) and
exprBody=iterStmtValue(stmt) and
exprBodyIter=iterExpr(exprBody) and
exprStoreIter=iterExpr(exprStore) and
varName=expr2string(exprStoreIter)  and
location=exprBodyIter.getLocation() and
//f.getAbsolutePath()="/opt/src/pro/builders/optimizer_builder.py" and
loc=getLocText(location) and
storeLoc=getLocText(exprStoreIter.getLocation()) and
dependVar=expr2string(exprBodyIter) and
scopeName=getScopeName(scope)
select f,mod,scope,varName,stmt,exprBody,dependVar,scopeName,loc,storeLoc


// from File f,Module mod,Scope scope, Variable var,string scopeName,string dependVar,Expr exprBody,Name varName,Location loc,Stmt stmt
// where
// //isSource(f) and
// varName=var.getAStore() and
// scope=varName.getScope() and
// mod=scope.getEnclosingModule() and
// f=mod.getFile() and
// //f.getAbsolutePath()="/opt/src/pro/builders/optimizer_builder.py" and
// loc=stmt.getLocation() and
// stmt.getASubExpression().defines(var) and
// exprBody=iterStmtValue(stmt) and
// dependVar=iterVarInExpr(exprBody) and
// scopeName=getScopeName(scope)
// select f,mod,scope,varName,stmt,exprBody,dependVar,scopeName,loc


// from Expr attr,Expr obj
// where
// attr instanceof Attribute and
// obj=attr.(Attribute).getObject()
// select attr,obj
// from File f,Module mod,Scope scope,Stmt stmt,Location loc,Expr expr,string targetVarName,string operation,string filePath,string moduleName,string scopeName
// where stmt=getWriteVariableSentence(stmt) and
// loc=stmt.getLocation() and
// isParentOfStmt(f, mod, scope, stmt) and
// filePath=f.getAbsolutePath() and
// scopeName=scope.toString() and
// moduleName=mod.toString() and
// expr=getCodeOfWriteAction(stmt) and
// targetVarName=getTargetVarName(stmt) and
// operation=getOperationName(stmt)

// select targetVarName,expr,operation,loc